% Ejercicio "Evaluación de polinomios"
\subsection*{\fbox{\theejercicio} - Evaluaci\'on de polinomios}

Se desea construir mediante LEX y YACC un int\'erprete de funciones polin\'omicas de una variable {\tt x}. Este int\'erprete tendr\'a como entrada una funci\'on definida sobre {\tt x}, o bien, una asignaci\'on temporal de valores a dicha variable. En el primer caso, el int\'erprete procede a almacenar la funci\'on, y en el segundo, responde con la evaluaci\'on de la funci\'on actual en el punto dado. El siguiente es un ejemplo de interacci\'on:

\begin{center}
\begin{tabular}{|l|} \hline
\verb@>  3x2 + 2x +1 ;@   \\
\verb@Funcion almacenada@ \\
\verb@>  x = 2;@          \\
\verb@17@                 \\
\verb@>  x = 3;@          \\
\verb@44@                 \\
\verb@>  x = -1;@         \\
\verb@2@                  \\
\verb@>  x2 - 1 ;@        \\
\verb@Funcion almacenada@ \\
\verb@>  x = -1;@         \\
\verb@0@                  \\
\verb@>  x = 2 ;@         \\
\verb@3@                  \\
\verb@>  y = 2x ;@        \\
\verb@Error@              \\ \hline
\end{tabular}
\end{center}

% Solución del ejercicio
\subsubsection*{SOLUCI\'ON}

\underline{ESPECIFICACI\'ON LEX}:

\begin{verbatim}
%{
#include "y.tab.h"
%}

%%
0|[1-9][0-9]*         {
                         yylval.valor = atoi(yytext);
                         return NUMERO;
                      }
[-+=;]                {
                          return yytext[0];
                      }
[xX]                  {
                          return EQUIS;
                      }
.|\n                  ;
%%

int yywrap() {
    return 1;
}
%%
\end{verbatim}

\underline{ESPECIFICACI\'ON YACC}:

\begin{verbatim}
%{
#define MAX 10
#include <math.h>
int coeficiente[MAX]; /* se supone que el maximo polinomio es de
                         grado MAX-1 */
%}

%union{
    int valor;
    struct {
       int coeficiente;
       int grado;
    } tipomonomio;
}

%type <tipomonomio> monomio

%token  <valor> NUMERO
%token  EQUIS

%right `='
%left  `+'
%left  `-'
%nonassoc MENOSUNARIO

%%

axioma: axioma linea
      | { printf("> "); } linea;
      ;

linea : polinomio `;' { printf("Funcion correcta\n> "); }
      | EQUIS `=' NUMERO `;' {
              int i=0;
              double valor = 0;
              for(i=0; i<MAX; i++) {
                 valor += coeficiente[i] * pow($3,i);
              }
              printf("%f\n> ",valor);
        }
      | `;' { printf("FIN\n"); exit(0); }
      ;


polinomio: polinomio `+' monomio 
              {
                 coeficiente[$3.grado] += $3.coeficiente;
              }
         | polinomio `-' monomio
              {
                 coeficiente[$3.grado] -= $3.coeficiente;
              }
         | monomio       {
                            int i=0; 
                            for(i=0; i<MAX; i++) {
                               coeficiente[i] = 0;
                            }
                            coeficiente[$1.grado] = $1.coeficiente; 
                         }
         | `-' monomio   {
                            int i=0; 
                            for(i=0; i<MAX; i++) {
                               coeficiente[i] = 0;
                            }
                            coeficiente[$2.grado] = - $2.coeficiente; 
                         }
         ;

monomio: NUMERO                { $$.coeficiente = $1; $$.grado = 0; }
       | NUMERO EQUIS          { $$.coeficiente = $1; $$.grado = 1; }
       | EQUIS                 { $$.coeficiente = 1;  $$.grado = 1; }
       | NUMERO EQUIS NUMERO   { $$.coeficiente = $1; $$.grado = $3;} 
       | EQUIS NUMERO          { $$.coeficiente = 1;  $$.grado = $2;} 
       ;



%%

int main() {
    yyparse();
}


void yyerror(char* s) {
    printf("ERROR %s\n",s);
}
\end{verbatim}